use std::io;

#[derive(Debug, Clone)]
struct MotorParams {
    pulse_count_per_revolution: u32, // 电机每圈脉冲数 (PPR)
    lead: f32,                      // 丝杠导程 (mm/rev)
    reduction_ratio: u8,            // 减速比 (N:1)
}

impl MotorParams {
    // 带默认值的构造器
    fn new(lead: f32, reduction_ratio: u8) -> Self {
        Self {
            pulse_count_per_revolution: 1000,  // 默认脉冲数
            lead,  // 直接使用参数值
            reduction_ratio,
        }
    }

    /// 计算每个脉冲对应的直线位移 (mm/pulse)
    fn displacement_per_pulse(&self) -> f32 {
        self.lead / (self.pulse_count_per_revolution as f32 * self.reduction_ratio as f32)
    }

    /// 计算负载移动指定距离所需的脉冲数
    fn pulses_for_distance(&self, distance_mm: f32) -> u32 {
        (distance_mm / self.displacement_per_pulse()).round() as u32
    }

    /// 计算电机旋转角度所需的脉冲数
    fn pulses_for_rotation(&self, degrees: f32) -> u32 {
        (degrees / 360.0 * self.pulse_count_per_revolution as f32).round() as u32
    }
}


fn main() {
    let motor = MotorParams::new(5.0, 1);

    // 计算并显示关键参数
    println!("电机参数: {:?}", motor);
    println!("每脉冲位移: {:.6} mm", motor.displacement_per_pulse());
    
    // 交互式输入循环
    loop {
        println!("\n请选择操作:");
        println!("1. 输入距离(mm)计算脉冲数");
        println!("2. 输入角度( °)计算脉冲数");
        println!("3. 退出程序");
        
        let mut choice = String::new();
        io::stdin()
            .read_line(&mut choice)
            .expect("读取输入失败");
        
        match choice.trim() {
            "1" => {
                println!("请输入距离(mm):");
                let mut input = String::new();
                io::stdin()
                    .read_line(&mut input)
                    .expect("读取输入失败");
                
                match input.trim().parse::<f32>() {
                    Ok(distance) => {
                        let pulse = motor.pulses_for_distance(distance);
                        println!("\n移动 {:.2} mm 需要脉冲数: 10进制:{:32}  16进制:{:#032X}", 
                                 distance, pulse, pulse);
                    }
                    Err(_) => println!("输入无效，请输入数字"),
                }
            }
            "2" => {
                println!("请输入角度(°):");
                let mut input = String::new();
                io::stdin()
                    .read_line(&mut input)
                    .expect("读取输入失败");
                
                match input.trim().parse::<f32>() {
                    Ok(degrees) => {
                        let pulse = motor.pulses_for_rotation(degrees);
                        println!("\n旋转 {:.0}°      需要脉冲数: 10进制:{:32}  16进制:{:#032X}", 
                                 degrees, pulse, pulse);
                    }
                    Err(_) => println!("输入无效，请输入数字"),
                }
            }
            "3" => {
                println!("程序退出");
                break;
            }
            _ => println!("无效选择，请输入1、2或3"),
        }
    }
}